﻿//sharepoint data mapper.
//SKB KONTUR 2012, v.1.4.6
var SharePointOrmIncluded = true;
SharePointOrm = (function () {
    function sharePointOrm() {
        if (typeof (window._spPageContextInfo) != "undefined") {
            var webPrefix = window._spPageContextInfo.webServerRelativeUrl;

            if (webPrefix.indexOf("/", webPrefix.length - 1) !== -1) {
                this.webPrefix = window._spPageContextInfo.webServerRelativeUrl;
            }
            else {
                this.webPrefix = window._spPageContextInfo.webServerRelativeUrl + "/";
            }

        } else {
            var links = document.getElementsByTagName("head")[0].getElementsByTagName("link");
            var spsdiscoUrl = "";
            for (var i = 0; i < links.length; i++) {
                var relAttr = links[i].getAttribute("rel");
                if (relAttr == null || relAttr != "alternate") continue;
                spsdiscoUrl = links[i].getAttribute("href");
                break;
            }
            this.webPrefix = spsdiscoUrl.substr(0, spsdiscoUrl.length - 22);
        }
    }

    sharePointOrm.prototype.processWebUrl = function (webUrl) {
        if (typeof (webUrl) == 'undefined')
            return this.webPrefix;

        if (webUrl.startsWith("http://") || webUrl.startsWith("https://"))
            return webUrl;
        if (webUrl.startsWith("/"))
            return webUrl;
        return this.webPrefix + webUrl;
    };

    sharePointOrm.prototype.getSPListItems = function (listName, viewName, query, viewFields, rowLimit, queryOptions, successFunc, errorFunc, webUrl) {
        if (rowLimit == 0)
            rowLimit = 1000;
        var parameters = {};
        parameters.listName = listName;
        if (typeof (query) != 'undefined' && query != null)
            parameters.query = query;
        if (typeof (viewFields) != 'undefined' && viewFields != null)
            parameters.viewFields = viewFields;
        if (typeof (viewName) != 'undefined' && viewName != null)
            parameters.viewName = viewName;
        if (typeof (rowLimit) != 'undefined' && rowLimit != null)
            parameters.rowLimit = rowLimit;
        if (typeof (queryOptions) != 'undefined' && queryOptions != null && queryOptions.length > 0)
            parameters.queryOptions = queryOptions;

        var soapEnv = this.buildSoapEnvelope("GetListItems", parameters);

        var url = this.processWebUrl(webUrl);

        var $this = this;
        this.makeSoapCall(url + "_vti_bin/lists.asmx", soapEnv, "", function (result) {
            var listItems = $this.getResponseRows(result.responseXML);

            //options:
            var options = {};
            var datanode;
            if (typeof result.responseXML.getElementsByTagNameNS == "undefined") {
                datanode = result.responseXML.getElementsByTagName("rs:data");
            } else {
                datanode = result.responseXML.getElementsByTagNameNS("urn:schemas-microsoft-com:rowset", "data");
            }
            if (datanode.length > 0) {
                for (var attr, i = 0, attrs = datanode[0].attributes, l = attrs.length; i < l; i++) {
                    attr = attrs.item(i);
                    options[attr.nodeName] = attr.nodeValue;
                }
            }
            if (typeof (successFunc) != 'undefined')
                successFunc(listItems, options);
        }, function (result) {
            if (typeof (errorFunc) == 'undefined')
                return;
            var ex = {};
            var errorMessageElement = result.responseXML.getElementsByTagName("errorstring");
            ex.errorMessage = errorMessageElement.length > 0 && errorMessageElement[0].firstChild != null ? errorMessageElement[0].firstChild.nodeValue : "";

            var errorCodeElement = result.responseXML.getElementsByTagName("errorcode");
            ex.errorCode = errorCodeElement.length > 0 && errorCodeElement[0].firstChild != null ? errorCodeElement[0].firstChild.nodeValue : "";
            errorFunc(ex);
        });
    };
    sharePointOrm.prototype.getResponseRows = function (doc) {
        var elms;
        if (typeof doc.getElementsByTagNameNS == "undefined") {
            elms = doc.getElementsByTagName("z:row");
        } else {
            elms = doc.getElementsByTagNameNS("#RowsetSchema", "row");
        }
        var rows = [];
        for (var j = 0; j < elms.length; j++) {
            var row = {};
            for (var attr, i = 0, attrs = elms[j].attributes, l = attrs.length; i < l; i++) {
                attr = attrs.item(i);
                var nodeName = (attr.nodeName.startsWith("ows_") ? attr.nodeName.substr(4) : attr.nodeName);
                row[nodeName] = attr.nodeValue;
            }
            rows.push(row);
        }
        return rows;
    };

    /* List items operations: */
    sharePointOrm.prototype.addSPListItems = function (listname, items, callback, webUrl) {
        var batch = this.buildBatchMessage(items, "New");
        this.updateListItems(listname, batch, callback, webUrl);
    };
    sharePointOrm.prototype.updateSPListItems = function (listname, items, callback, webUrl) {
        var batch = this.buildBatchMessage(items, "Update");
        this.updateListItems(listname, batch, callback, webUrl);
    };
    sharePointOrm.prototype.deleteSPListItems = function (listname, items, callback, webUrl) {
        var batch = this.buildBatchMessage(items, "Delete");
        this.updateListItems(listname, batch, callback, webUrl);
    };
    /* User profile operations: */
    sharePointOrm.prototype.getUserProfileByName = function (accountName, successFunc, errorFunc) {
        var parameters = {};
        parameters.AccountName = accountName;
        var soapEnv = this.buildSoapEnvelope("GetUserProfileByName", parameters, "http://microsoft.com/webservices/SharePointPortalServer/UserProfileService");

        var url = this.webPrefix;

        this.makeSoapCall(url + "_vti_bin/UserProfileService.asmx", soapEnv, "http://microsoft.com/webservices/SharePointPortalServer/UserProfileService/GetUserProfileByName", function (result) {
            var properites = result.responseXML.getElementsByTagName("PropertyData");
            var userProperties = {};
            for (var i = 0; i < properites.length; i++) {
                var propertyName = properites[i].getElementsByTagName("Name");
                if (propertyName.length == 0 || propertyName[0].firstChild.nodeValue.length == 0) continue;
                var propertyNameText = propertyName[0].firstChild.nodeValue.replace(/-/g, "_");
                var propertyValue = properites[i].getElementsByTagName("Value");
                if (propertyValue.length != 1) continue; ;
                userProperties[propertyNameText] = propertyValue[0].firstChild.nodeValue;
            }
            if (typeof (successFunc) != 'undefined')
                successFunc(userProperties);
        }, function () {
            if (typeof (errorFunc) != 'undefined')
                errorFunc();
        });
    };

    sharePointOrm.prototype.buildBatchMessage = function (items, command) {
        var itemsArray = this.isArray(items) ? items : [items];
        // building batch message
        var batch = "<Batch OnError=\"Continue\">";
        for (var i = 0; i < itemsArray.length; i++) {
            batch += "<Method ID=\"" + (i + 1) + "\" Cmd=\"" + command + "\">";
            for (var field in itemsArray[i]) {
                if (typeof (itemsArray[i][field]) != "function") {
                    batch += "<Field Name=\"" + field + "\">" + itemsArray[i][field] + "</Field>";
                }
            }
            batch += "</Method>";
        }
        batch += "</Batch>";
        return batch;
    };
    sharePointOrm.prototype.buildSoapEnvelope = function (methodName, parameters, methodXmlns) {
        var parametersValue = "";
        for (var field in parameters) {
            if (typeof (parameters[field]) != "function") {
                parametersValue += "<" + field + ">" + parameters[field] + "</" + field + ">";
            }
        }
        var xmlns = (methodXmlns == undefined ? "http://schemas.microsoft.com/sharepoint/soap/" : methodXmlns);
        return "<?xml version=\"1.0\" encoding=\"utf-8\"?> \
            <soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \
                xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" \
                xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> \
              <soap:Body> \
                <" + methodName + " xmlns=\"" + xmlns + "\"> \
                " + parametersValue + " \
                </" + methodName + "> \
              </soap:Body> \
            </soap:Envelope>";

    };
    /*======================================================*/
    sharePointOrm.prototype.updateListItems = function (listname, batch, callback, webUrl) {
        var parameters = {};
        parameters.listName = listname;
        parameters.updates = batch;
        var soapEnv = this.buildSoapEnvelope("UpdateListItems", parameters);

        var url = this.processWebUrl(webUrl);

        var $this = this;
        this.makeSoapCall(url + "_vti_bin/lists.asmx", soapEnv, "http://schemas.microsoft.com/sharepoint/soap/UpdateListItems", function (result) {
            if (typeof (callback) == 'undefined') return;
            var listItems = $this.getResponseRows(result.responseXML);
            callback(listItems);
        });
    };

    sharePointOrm.prototype.getSPListCollection = function (successFunc, errorFunc, webUrl) {
        var soapEnv = this.buildSoapEnvelope("GetListCollection", {});

        var url = this.processWebUrl(webUrl);

        this.makeSoapCall(url + "_vti_bin/lists.asmx", soapEnv, "", function (result) {
            var lists = [];

            var listsElmnts = result.responseXML.getElementsByTagName("List");
            for (var i = 0; i < listsElmnts.length; i++) {
                var list = {};
                for (var attr, j = 0, attrs = listsElmnts[i].attributes, l = attrs.length; j < l; j++) {
                    attr = attrs.item(j);
                    var nodeName = (attr.nodeName.startsWith("ows_") ? attr.nodeName.substr(4) : attr.nodeName);
                    list[nodeName] = attr.nodeValue;
                }
                lists.push(list);
            }

            if (typeof (successFunc) != 'undefined')
                successFunc(lists);
        }, function () {
            if (typeof (errorFunc) != 'undefined')
                errorFunc();
        });
    };

    sharePointOrm.prototype.getSPViewCollection = function (listname, successFunc, errorFunc, webUrl) {
        var parameters = {};
        parameters.listName = listname;
        var soapEnv = this.buildSoapEnvelope("GetViewCollection", parameters);

        var url = this.processWebUrl(webUrl);

        this.makeSoapCall(url + "_vti_bin/views.asmx", soapEnv, "", function (result) {
            var viewsElmnts = result.responseXML.getElementsByTagName("View");
            var views = [];
            for (var j = 0; j < viewsElmnts.length; j++) {
                var view = {};
                for (var attr, i = 0, attrs = viewsElmnts[j].attributes, l = attrs.length; i < l; i++) {
                    attr = attrs.item(i);
                    var nodeName = (attr.nodeName.startsWith("ows_") ? attr.nodeName.substr(4) : attr.nodeName);
                    view[nodeName] = attr.nodeValue;
                }
                views.push(view);
            }
            if (typeof (successFunc) != 'undefined')
                successFunc(views);
        }, function () {
            if (typeof (errorFunc) != 'undefined')
                errorFunc();
        });
    };
    /* AJAX */
    sharePointOrm.prototype.makeAjaxCall = function (url, soapEnv, soapAction, successFunc, errorFunc) {
        $.ajax({
            url: url,
            beforeSend: function (xhr) {
                if (soapAction != undefined && soapAction.length > 0)
                    xhr.setRequestHeader("SOAPAction", soapAction);
            },
            type: "POST",
            dataType: "xml",
            data: soapEnv,
            complete: function (result) {
                if (typeof (successFunc) != 'undefined')
                    successFunc(result);
            },
            error: function () {
                errorFunc();
            },
            contentType: "text/xml; charset=\"utf-8\""
        });
    };
    sharePointOrm.prototype.makeSoapCall = function (url, soapEnv, soapAction, successFunc, errorFunc) {
        var xhr = this.getXmlHttp();
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (xhr.status === 200 && typeof successFunc != "undefined") {
                    successFunc(xhr);
                }
                else if (typeof errorFunc != "undefined") {
                    errorFunc(xhr);
                }
            }
        };

        //set up the soap xml web service call
        xhr.open("POST", url, true);

        xhr.setRequestHeader("Content-Type", "text/xml; charset=\"utf-8\"");
        if (soapAction != undefined && soapAction.length > 0)
            xhr.setRequestHeader("SOAPAction", soapAction);


        xhr.send(soapEnv);
    };
    sharePointOrm.prototype.getXmlHttp = function () {
        try {
            return new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                return new ActiveXObject("Microsoft.XMLHTTP");
            } catch (ee) {
            }
        }
        if (typeof window.XMLHttpRequest != 'undefined') {
            return new window.XMLHttpRequest();
        }
        return null;
    };
    sharePointOrm.prototype.isArray = function (input) {
        return typeof (input) == 'object' && (input instanceof Array);
    };
    sharePointOrm.prototype.buildCamlElements = function (values, fieldName, valuesType, compareOperator, operator, lookupId) {
        var total = "<" + operator + ">";
        var sLookupId = "";
        if (lookupId)
            sLookupId = "LookupId='TRUE'";
        total += "<" + compareOperator + "><FieldRef " + sLookupId + " Name='" + fieldName + "' /><Value Type='" + valuesType + "'>" + values[0] + "</Value></" + compareOperator + ">";
        if (values.length > 2) {
            total += this.buildCamlElements(values.splice(1), fieldName, valuesType, compareOperator, operator, lookupId);
        } else if (values.length == 2) {
            total += "<" + compareOperator + "><FieldRef " + sLookupId + " Name='" + fieldName + "' /><Value Type='" + valuesType + "'>" + values[1] + "</Value></" + compareOperator + ">";
        } else if (values.length == 1) {
            return "<" + compareOperator + "><FieldRef " + sLookupId + " Name='" + fieldName + "' /><Value Type='" + valuesType + "'>" + values[0] + "</Value></" + compareOperator + ">";
        }
        total += "</" + operator + ">";
        return total;
    };

    return sharePointOrm;
})();
String.prototype.startsWith = function (str) {
    return this.indexOf(str) == 0;
};
String.prototype.endsWith = function (suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
};

window.SPData = new SharePointOrm();

// SharePoint Lookup Collection (1;#Sample)
SPFieldLookupCollection = (function () {

    function spFieldLookupCollection(lookuptext) {
        this.Items = [];
        var re = /(\d+)\;[#](.+?)(\;|$)/g;
        var m = re.exec(lookuptext);
        while (m != null) {
            var newLookupItem = {};
            newLookupItem["LookupValue"] = m[2];
            newLookupItem["LookupId"] = parseInt(m[1]);
            this.Items.push(newLookupItem);
            m = re.exec(lookuptext);
        }
        return this.Items;
    }

    return spFieldLookupCollection;
})();

//SharePoint DateTime
SPDateTime = (function () {
    var dateTime = new Date(0);

    function spDateTime(dateTimeText) {
        var re = /(\d{4})\-(\d{2})\-(\d{2})\s(\d{2})\:(\d{2})\:(\d{2})/g;
        var m = re.exec(dateTimeText);
        if (m != null) {
            dateTime.setYear(parseInt(m[1], 10));
            dateTime.setMonth(parseInt(m[2], 10) - 1, parseInt(m[3], 10));
            dateTime.setHours(parseInt(m[4], 10));
            dateTime.setMinutes(parseInt(m[5], 10));
            dateTime.setSeconds(parseInt(m[6], 10));
        }
        return dateTime;
    }

    return spDateTime;
})();